/*
 * Copyright (c) 2022, SHANGHAI FUDAN MICROELECTRONICS GROUP CO., LTD.(FUDAN MICROELECTRONICS./ FUDAN
 * MICRO.) All rights reserved.
 *
 * Processor:                   FM33LG0xxA
 * http:                        http://www.fmdevelopers.com.cn/
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * 4. To provide the most up-to-date information, the revision of our documents
 *    on the World Wide Web will be the most Current. Your printed copy may be
 *    an earlier revision. To verify you have the latest information avaliable,
 *    refer to: http://www.fmdevelopers.com.cn/.
 *
 * THIS SOFTWARE IS PROVIDED BY FUDAN MICRO "AS IS" AND ANY EXPRESSED
 * ORIMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.IN NO EVENT SHALL FUDAN MICRO OR ITS CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISINGIN ANY WAY OUT OF THE
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OFTHE POSSIBILITY OF SUCH DAMAGE.
 */

/* Includes ------------------------------------------------------------------*/
#include "mf_config.h"

#include "fm33lg0xx_fl.h"

/* Private function prototypes -----------------------------------------------*/

/**
 * @brief  CMU_XTHF Initialization function
 * @param  void
 * @retval None
 */
void MF_CMU_XTHF_Init(void)
{
    FL_GPIO_InitTypeDef GPIO_InitStruct;

    /* PC2 CMU_XTHI */
    GPIO_InitStruct.pin          = FL_GPIO_PIN_2;
    GPIO_InitStruct.mode         = FL_GPIO_MODE_ANALOG;
    GPIO_InitStruct.outputType   = FL_GPIO_OUTPUT_PUSHPULL;
    GPIO_InitStruct.pull         = FL_DISABLE;
    GPIO_InitStruct.remapPin     = FL_DISABLE;
    GPIO_InitStruct.analogSwitch = FL_DISABLE;
    FL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    /* PC3 CMU_XTHO */
    GPIO_InitStruct.pin          = FL_GPIO_PIN_3;
    GPIO_InitStruct.mode         = FL_GPIO_MODE_ANALOG;
    GPIO_InitStruct.outputType   = FL_GPIO_OUTPUT_PUSHPULL;
    GPIO_InitStruct.pull         = FL_DISABLE;
    GPIO_InitStruct.remapPin     = FL_DISABLE;
    GPIO_InitStruct.analogSwitch = FL_DISABLE;
    FL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    FL_CMU_XTHF_WriteDriverStrength(10);
}

/**
 * @brief  FDET_IRQHandler
 * @param  void
 * @retval None
 */
void FDET_IRQHandler(void)
{
    // 停振检测中断处理
    if ((FL_CMU_IsEnabledIT_XTHFFail() == 0x01UL) && (FL_CMU_IsActiveFlag_XTHFFail() == 0x01UL)) {
        FL_CMU_ClearFlag_XTHFFail();
        /*应用处理逻辑*/
    }
}

/**
 * @brief  The application entry point.
 * @retval int
 */
void MF_Clock_Init(void)
{
    FL_CMU_EnableGroup1BusClock(FL_CMU_GROUP1_BUSCLK_RTCA);
    FL_RTCA_WriteAdjustValue(RTCA, 0);
    FL_CMU_DisableGroup1BusClock(FL_CMU_GROUP1_BUSCLK_RTCA);
    FL_DelayInit(); // 必须有它，才能正常运行FreeRTOS
    FL_NVIC_ConfigTypeDef InterruptConfigStruct;

    /* Initial CDIF */
    FL_CDIF_EnableCPUToVAO(CDIF);
    FL_CDIF_EnableVAOToCPU(CDIF);

    /* Initial RTCA Adjust Value */
    FL_CMU_EnableGroup1BusClock(FL_CMU_GROUP1_BUSCLK_RTCA);
    FL_RTCA_WriteAdjustValue(RTCA, 0);
    FL_CMU_DisableGroup1BusClock(FL_CMU_GROUP1_BUSCLK_RTCA);

    /* Initial RTCB Adjust Value */
    // FL_RTCB_WriteAdjustValue(RTCB, 0);

    /* Initial XTLF */
    FL_VAO_XTLF_Enable(VAO);
    FL_DelayMs(1000);

    /* Initial Low Speed Clock */
    FL_CMU_SetLSCLKClockSource(FL_CMU_LSCLK_CLK_SOURCE_RCLP);

    /* Initial RCHF */
    FL_CMU_RCHF_WriteTrimValue(RCHF8M_TRIM);
    FL_CMU_RCHF_SetFrequency(FL_CMU_RCHF_FREQUENCY_8MHZ);
    FL_CMU_RCHF_Enable();

    /* Initial XTHF */
    MF_CMU_XTHF_Init();
    FL_CMU_XTHF_Enable();
    FL_DelayMs(2);
    FL_CMU_ClearFlag_XTHFFail();
    FL_CMU_EnableIT_XTHFFail();
    InterruptConfigStruct.preemptPriority = 2;
    FL_NVIC_Init(&InterruptConfigStruct, FDET_IRQn);
    XTHFClock = 8000000; /*  外接晶体频率: 8MHz  */

    /* Initial PLL */
    FL_CMU_PLL_Disable();
    FL_CMU_PLL_SetClockSource(FL_CMU_PLL_CLK_SOURCE_XTHF);
    FL_CMU_PLL_SetPrescaler(FL_CMU_PLL_PSC_DIV8);
    FL_CMU_PLL_WriteMultiplier(63); // PLL输出范围32-64MHz
    FL_CMU_PLL_SetOutputMultiplier(FL_CMU_PLL_OUTPUT_X1);
    FL_CMU_PLL_Enable();
    while (FL_CMU_IsActiveFlag_PLLReady() != FL_SET);

    /* Initial System Clock */
    FL_FLASH_SetReadWait(FLASH, FL_FLASH_READ_WAIT_2CYCLE);    /* 设置FLASH读等待为 2 个周期 */
    FL_CMU_SetSystemClockSource(FL_CMU_SYSTEM_CLK_SOURCE_PLL); /* 设置系统主时钟为 PLL */
    FL_CMU_SetAHBPrescaler(FL_CMU_AHBCLK_PSC_DIV1);
    FL_CMU_SetAPBPrescaler(FL_CMU_APBCLK_PSC_DIV1);

    /* Initial CDIF Clock Prescaler */
    FL_CDIF_SetPrescaler(CDIF, FL_CDIF_PSC_DIV8);

    SystemCoreClockUpdate();
}

/**
 * @brief System Clock Configuration
 * @retval None
 */
void MF_SystemClock_Config(void) {}

void MF_Config_Init(void) {}

/**
 * @brief  This function is executed in case of error occurrence.
 * @retval None
 */
void Error_Handler(void)
{
    /* USER CODE BEGIN Error_Handler_Debug */
    /* User can add his own implementation to report the HAL error return state */

    /* USER CODE END Error_Handler_Debug */
}

/**
 * @brief  HardFault 中断服务函数 请保留
 * @param  void
 * @retval None
 */
void HardFault_Handler(void)
{
    /* 软复位MCU */
    FL_RMU_SetSoftReset(RMU);
}

#ifdef USE_FULL_ASSERT
/**
 * @brief  Reports the name of the source file and the source line number
 *         where the assert_param error has occurred.
 * @param  file: pointer to the source file name
 * @param  line: assert_param error line source number
 * @retval None
 */
void assert_failed(uint8_t *file, uint32_t line)
{
    /* USER CODE BEGIN Assert_Failed */
    /* User can add his own implementation to report the file name and line number,
       tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
    /* USER CODE END Assert_Failed */
}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT FMSH *****END OF FILE****/
